#ifndef PROTOCOL_DEFINE_H
#define PROTOCOL_DEFINE_H

#include <stdint.h>

#define     PROTOCOL_VERSION    "1.1.2"

#define SENSOR_STATE(x) (x==0?0:1)
#define CURRENT_TIME_STUPY (uint32_t)0xf4f3f2f1 // 假时间
#define PACK_END (uint16_t)0xfafd   // 包尾
#define SUCCESS     1
#define FAILURE     0
#define INVALID     2

#pragma pack (1) /*指定按1字节对齐*/

enum protocol_type : uint8_t{
    type_dipan_pc_heart         = 0x00, //心跳
    type_dipan_pc_ult           = 0x01, //超声波
    type_dipan_pc_other         = 0x02, //其他，安全触边、软关机等其他信息
    type_dipan_pc_encoder       = 0x03, //轮子编码器数据
    type_dipan_pc_speed         = 0x04, //车速（线速度，角速度）
    type_dipan_pc_reply         = 0x05, //返回报文
    type_dipan_pc_imu           = 0x06, //imu数据
    type_dipan_pc_status        = 0x07, //各开关状态
    type_dipan_pc_alarm         = 0x08, //告警状态

    type_pc_dipan_switch        = 0x10, //充电刷片继电器开关控制
    type_pc_dipan_ackerman      = 0x11, //发送阿克曼目标速度
    type_pc_dipan_reset_odom    = 0x12, //重置里程计
    type_pc_dipan_fine_control  = 0x13, //精细控制
    type_pc_dipan_motion_mode   = 0x14, //运动模式
    type_pc_dipan_cmd           = 0x15, //控制命令
    type_pc_dipan_time_sync     = 0x16, //时戳同步
    type_pc_dipan_heart         = 0x17, //心跳
    type_pc_dipan_steer_engine  = 0x18, //二维码相机舵机刷子

    type_dianyuan_pc_heart      = 0x20, //心跳
    type_dianyuan_pc_battery    = 0x21, //电池数据
    type_dianyuan_pc_status     = 0x22, //各开关状态
    type_dianyuan_pc_reply      = 0x23, //返回报文
    type_dianyuan_pc_radar      = 0x24, //毫米波雷达
    type_dianyuan_pc_func_flag  = 0x25, //特殊功能信息上报
    type_dianyuan_pc_alarm      = 0x26, //告警状态

    type_pc_dianyuan_switch     = 0x30, //继电器开关
    type_pc_dianyuan_state      = 0x31, //状态切换
    type_pc_dianyuan_time_sync  = 0x32, //时戳同步
    type_pc_dianyuan_heart      = 0x33, //心跳
    type_pc_dianyuan_func_set   = 0x34, //特殊功能设置
    type_pc_dianyuan_charge_id  = 0x35, //充电器ID
};

/*****************************************共用**************************************************/
//包头
typedef struct
{
    uint8_t head;
    uint8_t protocol_version;
    enum protocol_type protocol_type;
    uint8_t temp;
    uint16_t data_length;
    uint32_t current_time;
} protocol_head;

/*****************************************底盘->上位机*****************************************/
// 心跳报文，类型：type_dipan_pc_heart，底盘->上位机
typedef struct
{
    protocol_head protocol_head;
    uint8_t state;
    uint8_t error;
    uint8_t version1;
    uint8_t version2;
    uint8_t version3;
    uint8_t dynamic;
    uint16_t crc16; //all of the protocol
    uint16_t end;
} protocol_dipan_pc_heart;

// 超声波，类型：type_dipan_pc_ult，底盘->上位机
typedef struct
{
    protocol_head protocol_head;
    float lf;   //左前
    float rf;   //右前
    float lb;   //左后
    float rb;   //右后
    uint16_t crc16; //all of the protocol
    uint16_t end;
} protocol_dipan_pc_ult;

// 其他(安全触边、轮子状态)，类型：type_dipan_pc_other，底盘->上位机
typedef struct
{
    protocol_head protocol_head;
    uint8_t safe_edge_front;
    uint8_t safe_edge_back;
    uint8_t state_line_lf;
    uint8_t state_line_rf;
    uint8_t state_line_lb;
    uint8_t state_line_rb;
    uint8_t state_roll_lf;
    uint8_t state_roll_rf;
    uint8_t state_roll_lb;
    uint8_t state_roll_rb;
    uint8_t vel_controller_state; // Bit8 0-离线 1在线 bit4-Bit1 0-自动 1-手动 2-停止
    uint8_t steer_engine_state;
    uint8_t nc1;
    uint8_t nc2;
    uint16_t crc16; //all of the protocol
    uint16_t end;
} protocol_dipan_pc_other;

// 轮子编码器数据，类型：type_dipan_pc_encoder，底盘->上位机
typedef struct
{
    protocol_head protocol_head;
    uint64_t timestamp;
    float speed_lf; // l:left r:right f:front b:back
    float speed_rf; // 单位:m/s
    float speed_lb;
    float speed_rb;
    float degrees_lf; // l:left r:right f:front b:back
    float degrees_rf; // 单位:°
    float degrees_lb;
    float degrees_rb;
    int32_t line_lf; // l:left r:right f:front b:back
    int32_t line_rf; // 单位:cnt
    int32_t line_lb;
    int32_t line_rb;
    uint16_t crc16; //all of the protocol
    uint16_t end;
} protocol_dipan_pc_encoder;

// 里程计与车速，类型：type_dipan_pc_speed，底盘->上位机
typedef struct
{
    protocol_head protocol_head;
    uint64_t timestamp;	//imu时戳
    float p_x;	// x方向位移
    float p_y;	// y方向位移
    float v_x;	// x方向速度
    float v_y;	// y方向速度
    float w_z;	// z方向角速度
    float deg_z;// 航向角
    uint8_t mode; // 1: 四轮ackman 2: 两轮ackman 3: 差速
    uint8_t stop_flag; // 停止标志位，停车时为1
    uint16_t crc16; //all of the protocol
    uint16_t end;
} protocol_dipan_pc_speed;

// 返回报文，类型：type_dipan_pc_reply，底盘->上位机
typedef struct
{
    protocol_head protocol_head;
    uint8_t res;
    uint16_t type;	//类型
    uint32_t time;	//报文索引
    uint16_t crc16;	//all of the protocol
    uint16_t end;
} protocol_dipan_pc_reply;

// IMU，类型：type_dipan_pc_imu，底盘->上位机
typedef struct
{
    protocol_head protocol_head;

    uint64_t timestamp;	//imu时戳
    float roll;
    float pitch;
    float yaw;
    float acc_x;
    float acc_y;
    float acc_z;
    float gyro_x;
    float gyro_y;
    float gyro_z;
    float mag_x;
    float mag_y;
    float mag_z;
    uint16_t crc16;	//all of the protocol
    uint16_t end;
} protocol_dipan_pc_imu;

// 开关状态，类型：type_dipan_pc_status，底盘->上位机
typedef struct
{
    protocol_head protocol_head;
    uint32_t switch_flag;
    uint32_t switch_effective;
    uint16_t crc16;
    uint16_t end;
} protocol_dipan_pc_status;

// 告警状态，类型：type_dipan_pc_alarm，底盘->上位机
typedef struct
{
    protocol_head protocol_head;
    uint16_t alarm_type;
    uint8_t alarm_value;
    uint16_t crc16;
    uint16_t end;
} protocol_dipan_pc_alarm;

/*****************************************上位机->底盘*****************************************/
// 充电刷片继电器开关控制，类型：type_pc_dipan_switch，上位机->底盘
typedef struct
{
    protocol_head protocol_head;
    uint8_t switch_type;    // 0:充电继电器
    uint8_t switch_control;
    uint16_t crc16; //all of the protocol
    uint16_t end;
} protocol_pc_dipan_switch;

// 目标速度，类型：type_pc_dipan_ackerman，上位机->底盘
typedef struct
{
    protocol_head protocol_head;
    uint8_t mode;
    float v;	// 车体速度 m/s
    float w;	// 角速度 rad/s
    float r;	// 旋转半径 m
    float deg;	// 轮子朝向 单位°
    uint16_t crc16; //all of the protocol
    uint16_t end;
} protocol_pc_dipan_ackerman;

// 里程计清零，类型：type_pc_dipan_reset_odom，上位机->底盘
typedef struct
{
    protocol_head protocol_head;
    float x;
    float y;
    float yaw;
    uint16_t crc16; //all of the protocol
    uint16_t end;
} protocol_pc_dipan_reset_odom;

// 精细控制 类型：type_pc_dipan_fine_control，上位机->底盘
typedef struct
{
    protocol_head protocol_head;
    float v_lf;	// 速度 m/s
    float v_rf;
    float v_lb;
    float v_rb;
    float deg_lf; // 朝向角 °
    float deg_rf;
    float deg_lb;
    float deg_rb;
    uint16_t crc16; //all of the protocol
    uint16_t end;
} protocol_pc_dipan_fine_control;

// 运动模式 类型：type_pc_dipan_motion_mode，上位机->底盘
typedef struct
{
    protocol_head protocol_head;
    uint8_t mode;	//	1: 四轮ackman 2: 两轮ackman 3: 差速
    uint16_t crc16; //all of the protocol
    uint16_t end;
} protocol_pc_dipan_motion_mode;

// 控制命令 类型：type_pc_dipan_cmd，上位机->底盘
typedef struct
{
    protocol_head protocol_head;
    uint8_t cmd;	//	1: 四轮ackman 2: 两轮ackman 3: 差速
    uint16_t crc16; //all of the protocol
    uint16_t end;
} protocol_pc_dipan_cmd;

// 时戳同步 类型：type_pc_dipan_time_sync，上位机->底盘
typedef struct
{
    protocol_head protocol_head;
    uint64_t timestamp;
    uint16_t crc16; //all of the protocol
    uint16_t end;
} protocol_pc_dipan_time_sync;

// 心跳 类型 type_pc_dipan_heart, 上位机->底盘
typedef struct
{
    protocol_head protocol_head;
    uint8_t navigation_pc_state;
    uint8_t image_pc_state;
    uint16_t crc16;
    uint16_t end;
} protocol_pc_dipan_heart;

// 二维码相机舵机刷子 类型 type_pc_dipan_steer_engine, 上位机->底盘
typedef struct
{
    protocol_head protocol_head;
    uint8_t control;
    uint16_t crc16;
    uint16_t end;
} protocol_pc_dipan_steer_engine;

/*****************************************电源板->上位机*****************************************/
// 心跳，类型：type_dianyuan_pc_heart，电源板->上位机
typedef struct
{
    protocol_head protocol_head;
    uint8_t state;
    uint8_t error;
    uint8_t version1;
    uint8_t version2;
    uint8_t version3;
    uint8_t dynamic;
    uint16_t crc16;
    uint16_t end;
} protocol_dianyuan_pc_heart;

// 电池，类型：type_dianyuan_pc_battery，电源板->上位机
typedef struct
{
    protocol_head protocol_head;
    uint8_t charge_id;      // 1号电池底盘，2号电池上装
    uint8_t charge_flag;    // 充电标志 1充电，2不充电
    float current;          // 电流值 单位：1A 充电为正 放电为负
    float voltage;          // 总电压 单位：1V
    float leave_power;      // 剩余电量 单位：AH
    float sum_power;        // 总容量 单位：AH
    float percent;          // 百分比 单位：%
    float temperature;      // 温度 单位：℃
    uint16_t crc16;
    uint16_t end;
} protocol_dianyuan_pc_battery;

// 各开关状态，类型：type_dianyuan_pc_status，电源板->上位机
typedef struct
{
    protocol_head protocol_head;
    uint32_t switch_flag;
    uint32_t switch_effective;
    uint16_t crc16;
    uint16_t end;
} protocol_dianyuan_pc_status;

// 返回报文，类型：type_dianyuan_pc_reply，电源板->上位机
typedef struct
{
    protocol_head protocol_head;
    uint8_t res;
    uint16_t type; //类型
    uint32_t time;  //时间戳
    uint16_t crc16; //all of the protocol
    uint16_t end;
} protocol_dianyuan_pc_reply;

// 毫米波雷达，类型：type_dianyuan_pc_radar，电源板->上位机
#ifndef POINT_NUMBER
    #define POINT_NUMBER 4
#endif
typedef struct
{
    uint8_t Objects_ID; 		//目标ID
    float Objects_DistLong; 	//目标纵向距离
    float Objects_DistLat; 		//目标横向距离
    float Objects_VrelLong; 	//目标纵向速度
    float Objects_VrelLat; 		//目标横向速度
} radar_obj;
typedef struct
{
    protocol_head protocol_head;
    uint8_t radar_ID; //雷达编号 1:车前雷达 2:车后雷达
    uint8_t point_number; //该雷达有效点数 1~4
    radar_obj point[POINT_NUMBER];
    uint16_t crc16;
    uint16_t end;
} protocol_dianyuan_pc_radar;

// 特殊功能信息上报，类型：type_dianyuan_pc_func_flag，电源板->上位机
typedef struct
{
    protocol_head protocol_head;
    uint8_t emergency_stop;
    uint8_t pc_restart_func;
    uint8_t charge_func;
    uint8_t nc3;
    uint16_t crc16;
    uint16_t end;
} protocol_dianyuan_pc_func_flag;

// 告警状态，类型：type_dianyuan_pc_alarm，电源板->上位机
typedef struct
{
    protocol_head protocol_head;
    uint16_t alarm_type;
    uint8_t alarm_value;
    uint16_t crc16;
    uint16_t end;
} protocol_dianyuan_pc_alarm;

/*****************************************上位机->电源板*****************************************/
// 继电器开关，类型：type_pc_dianyuan_switch，上位机->电源板
typedef struct
{
    protocol_head protocol_head;
    uint8_t switch_type; //开关类型：
    uint8_t switch_control; //主电源开关 0：关闭  1：打开
    uint16_t crc16; //all of the protocol
    uint16_t end;
} protocol_pc_dianyuan_switch;

// 灯带状态，类型：type_pc_dianyuan_state，上位机->电源板
typedef struct
{
    protocol_head protocol_head;
    uint8_t state; //
    uint16_t crc16; //all of the protocol
    uint16_t end;
} protocol_pc_dianyuan_state;

// 时戳同步 类型：type_pc_dianyuan_time_sync，上位机->电源板
typedef struct
{
    protocol_head protocol_head;
    uint64_t timestamp;
    uint16_t crc16; //all of the protocol
    uint16_t end;
} protocol_pc_dianyuan_time_sync;

// 心跳 类型 type_pc_dianyuan_heart, 上位机->电源板
typedef struct
{
    protocol_head protocol_head;
    uint8_t navigation_pc_state;
    uint8_t image_pc_state;
    uint16_t crc16;
    uint16_t end;
} protocol_pc_dianyuan_heart;

// 特殊功能设置 类型 type_pc_dianyuan_func_set, 上位机->电源板
typedef struct
{
    protocol_head protocol_head;
    uint8_t func_id;
    uint8_t func_cmd;
    uint16_t crc16;
    uint16_t end;
} protocol_pc_dianyuan_func_set;

// 充电器 ID 配置 类型 type_pc_dianyuan_charge_id，上位机->电源板
typedef struct
{
    protocol_head protocol_head;
    uint8_t charge_id;
    uint16_t crc16;
    uint16_t end;
} protocol_pc_dianyuan_charge_id;

#pragma pack () /*取消指定对齐，恢复缺省对齐*/



#endif // PROTOCOL_DEFINE_H
